package org.cedar.syntaxcore;

/**
 * <p>Title: 行拆分单元 为CalcaulatorUtil单元用</p>
 * <p>Description:
 * 通过指定行分割符，对行进行拆分
 * 通过设置extraGap属性，可以指定多个分隔符
 * 通过设置notSurroundChar属性可以排除左右为notSurroundChar字符的假分割符
 * </p>
 * @author net.wzh
 * @version 1.0
 */
public class LineProcess {
    private String line = null;
    private char gap;
    private int pos = 0;
    private int size = 0;
    private char[] extraGap;
    private String[] notSurroundChar;
    public LineProcess() {
        this.extraGap = new char[0];
    }

    public LineProcess(char[] ext) {
        this.extraGap = ext;
    }

    public void setExtraGap(char[] ext) {
        this.extraGap = ext;
    }

    public void setNotSurroundChar(String[] notSurroundChar) {
        this.notSurroundChar = notSurroundChar;
    }

    public void setLineInfo(String line, char gap) {
        this.pos = 0;
        this.line = line;
        this.gap = gap;
        this.size = this.line.length();
    }

    private boolean charInArr(char c, char[] chars) {
    	for(int i =0;i<chars.length;i++){
    		if(c == chars[i])
    			return true;
    	}
    	return false;
    }
    private boolean charInSurround(int pos, String[] chars) {
        for (int i = 0; i < chars.length; i++){
        	boolean twins = chars[0] == chars[1];
        	//scan left
        	int tPos = pos;
        	int pairL = 0;
        	while(--tPos >-1){
        		if(chars[i].charAt(0) == this.line.charAt(tPos) ){
        			pairL--;
        		}
        		if(!twins && chars[i].charAt(1) == this.line.charAt(tPos) ){//jump if pair
        			pairL++;
        		}
        	}
        	if(!twins){
        		  return pairL < 0;
        	}
    		tPos = pos;
    		int pairR = 0;
    		int sL = this.line.length();
    		while(++tPos < sL){
    			if(chars[i].charAt(1) == this.line.charAt(tPos) ){
    				pairR++;
    			}
    		}
    		if((-pairL)%2 == 1 && 1 == pairR%2)
    			return true;
        }
        return false;
    }

    private boolean charIsGap(char c) {
    	boolean ret = c == this.gap;
    	if (!ret) {
    		ret = charInArr(c, extraGap);
    	} 
    	if(ret && this.notSurroundChar != null) {
    			ret = !charInSurround(pos, notSurroundChar);
    	}
        return ret;
    }

    public void jumpNext() {
        for (int i = pos; i < size; i++) {
            if (charIsGap(line.charAt(i))) {
                pos++;
                return;
            }
            pos++;
        }
    }

    public String next() {
        StringBuilder buf = new StringBuilder();
        for (int i = pos; i < size; i++) {
            if (this.charIsGap(line.charAt(i))) {
                pos++;
                return buf.toString();
            }
            buf.append(line.charAt(i));
            pos++;
        }
        pos = size;
        return buf.toString();
    }

    public boolean hasMoreElements() {
        return this.pos < this.size;
    }

    public int countTokens() {
        int ret = 0;
        int oldPos = this.pos;
        StringBuilder buf = new StringBuilder(this.line);
        while (buf.length() > 0 && this.charIsGap(buf.charAt(buf.length() - 1)))
            buf.setLength(buf.length() - 1);
        String tLine = buf.toString();
        buf = null;
        this.pos = 0;
        for (int i = 0; i < tLine.length(); i++) {
            if (this.charIsGap(tLine.charAt(i))) {
                ret++;
            }
            pos++;
        }
        this.pos = oldPos;
        return++ret;
    }
}
